package com.dc.juc.example._10_aqs;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * Description: CountDownLatch
 *
 *  countDownLatch这个类使一个线程等待其他线程各自执行完毕后再执行。
 *  是通过一个计数器来实现的，计数器的初始值是线程的数量。
 *  每当一个线程执行完毕后，计数器的值就-1，当计数器的值为0时，表示所有线程都执行完毕，然后在闭锁上等待的线程就可以恢复工作了。
 *
 *
 * @author: gdc
 * @date: 2021/8/13
 * @version 1.0
 */
@Slf4j
public class CountDownLatch1 {

    private static final int THREAD_COUNT = 200;

    @SneakyThrows
    public static void main(String[] args){
        ExecutorService threadPool = Executors.newCachedThreadPool();

        final CountDownLatch countDownLatch = new CountDownLatch(THREAD_COUNT);

        for (int i = 0; i < THREAD_COUNT; i++) {

            threadPool.execute(() -> {
                try {
                    test(Thread.currentThread().getId());
                } finally {

                    // countDown() 方法放在 finally块中，保证代码肯定会被执行到
                    countDownLatch.countDown();
                }
            });
        }

        // await() 方法，使当前线程等待其他线程执行结束后，才能向下继续执行
        countDownLatch.await();
        log.info("finish...");

        // 关闭线程池，调用shutdown()后，会在已经启动的线程执行完之后关闭
        threadPool.shutdown();
    }


    @SneakyThrows
    private static void test(long threadNum) {
        TimeUnit.MILLISECONDS.sleep(100);
        log.info("{}", threadNum);
    }

}
